package dao

import (
	"fmt"

	"gorm.io/gorm"
	"openeuler.org/PilotGo/PilotGo-plugin-automation/internal/global"
	jobstatus "openeuler.org/PilotGo/PilotGo-plugin-automation/internal/module/common/enum/job"
	"openeuler.org/PilotGo/PilotGo-plugin-automation/internal/module/job_history/model"
)

func CreateRetryJob(oldJobId string, newJobId string, retryReq *model.TaskRetryRequest) (*model.JobDTO, error) {
	var newJobDTO model.JobDTO

	err := global.App.MySQL.Transaction(func(tx *gorm.DB) error {
		// 1. 获取原作业基本信息
		var oldJob model.Job
		if err := tx.Where("job_id = ?", oldJobId).First(&oldJob).Error; err != nil {
			return fmt.Errorf("获取原作业信息失败: %v", err)
		}

		// 2. 确定重试的主机列表
		rootJobId := oldJobId
		if oldJob.RootJobId != "" {
			rootJobId = oldJob.RootJobId
		}

		retryCount := 1
		if oldJob.RetryCount > 0 {
			retryCount = oldJob.RetryCount + 1
		}

		execHosts := oldJob.ExecHosts
		if retryReq.RetryHosts != "" {
			execHosts = retryReq.RetryHosts
		}
		// 3. 创建新作业基本信息
		newJob := &model.Job{
			JobName:       fmt.Sprintf("%s(重试%d)", oldJob.JobName, retryCount),
			JobId:         newJobId,
			WorkflowId:    oldJob.WorkflowId,
			UsageType:     oldJob.UsageType,
			OperationType: oldJob.OperationType,
			JobType:       oldJob.JobType,
			ModifyUser:    oldJob.ModifyUser,
			JobStatus:     jobstatus.JobRunning, // 重试作业直接设置为运行中状态
			ExecHosts:     execHosts,
			ParentJobId:   oldJobId,            // 关联父任务
			RetryCount:    retryCount,          // 增加重试次数
			RetryStep:     retryReq.StepNum,    // 记录重试的起始步骤
			RetryHosts:    retryReq.RetryHosts, // 记录重试的特定主机列表
			RootJobId:     rootJobId,           // 关联根任务ID，用于追踪整个重试链
		}
		if err := tx.Create(newJob).Error; err != nil {
			return fmt.Errorf("创建重试作业记录失败: %v", err)
		}

		// 4. 获取并复制输入参数
		var inputParams []model.JobParams
		if err := tx.Where("job_id = ? AND workflow_id = ?", oldJobId, oldJob.WorkflowId).Find(&inputParams).Error; err != nil {
			return fmt.Errorf("获取原作业输入参数失败: %v", err)
		}

		if len(inputParams) > 0 {
			// 更新输入参数的job_id
			for i := range inputParams {
				inputParams[i].JobId = newJobId
				inputParams[i].ID = 0 // 重置ID，自动生成
			}
			if err := tx.Create(&inputParams).Error; err != nil {
				return fmt.Errorf("创建重试作业输入参数失败: %v", err)
			}
		}

		// 5. 获取并复制输出参数
		var outputParams []model.JobOutputParams
		if err := tx.Where("job_id = ? AND workflow_id = ?", oldJobId, oldJob.WorkflowId).Find(&outputParams).Error; err != nil {
			return fmt.Errorf("获取原作业输出参数失败: %v", err)
		}

		if len(outputParams) > 0 {
			// 更新输出参数的job_id
			for i := range outputParams {
				outputParams[i].JobId = newJobId
				outputParams[i].ID = 0 // 重置ID，自动生成
			}
			if err := tx.Create(&outputParams).Error; err != nil {
				return fmt.Errorf("创建重试作业输出参数失败: %v", err)
			}
		}

		// 6. 获取并复制子作业信息
		var subJobs []model.SubJob
		if err := tx.Where("job_id = ? AND workflow_id = ?", oldJobId, oldJob.WorkflowId).Find(&subJobs).Error; err != nil {
			return fmt.Errorf("获取原作业子任务失败: %v", err)
		}

		if len(subJobs) > 0 {
			// 更新子作业的job_id
			for i := range subJobs {
				subJobs[i].JobId = newJobId
				subJobs[i].ID = 0 // 重置ID，自动生成
			}
			if err := tx.Create(&subJobs).Error; err != nil {
				return fmt.Errorf("创建重试子作业记录失败: %v", err)
			}
		}

		// 构建新的JobDTO返回
		newJobDTO = model.JobDTO{
			Job:          *newJob,
			InputParams:  inputParams,
			OutputParams: outputParams,
			SubJobs:      subJobs,
		}

		return nil
	})

	if err != nil {
		return nil, err
	}

	return &newJobDTO, nil
}

// 添加获取关联任务的方法，支持多次重试链查询
func GetRelatedJobs(jobId string) ([]*model.Job, error) {
	var jobs []*model.Job

	// 首先查询该任务是否是重试任务，获取根任务ID
	var job model.Job
	if err := global.App.MySQL.Where("job_id = ?", jobId).First(&job).Error; err != nil {
		return nil, err
	}

	query := global.App.MySQL
	if job.RootJobId != "" {
		query = query.Where("root_job_id = ?", job.RootJobId)
	} else {
		// 否则查询直接关联的重试任务
		query = query.Where("parent_job_id = ?", jobId)
	}

	if err := query.Order("id asc").Find(&jobs).Error; err != nil {
		return nil, err
	}

	return jobs, nil
}

func GetRetryChain(rootJobId string) ([]*model.Job, error) {
	var jobs []*model.Job
	// 查询所有属于同一根任务的重试任务
	if err := global.App.MySQL.Where("root_job_id = ? OR job_id = ?", rootJobId, rootJobId).Order("id asc").Find(&jobs).Error; err != nil {
		return nil, err
	}
	return jobs, nil
}
